package it.unibz.ti2.internetPizzeria.dao;

import it.unibz.ti2.internetPizzeria.entities.Order;
import it.unibz.ti2.internetPizzeria.entities.OrderProduct;

import java.util.List;

import org.hibernate.Criteria;
import org.hibernate.Query;
import org.hibernate.Transaction;
import org.hibernate.criterion.Expression;

/**
 * Class responsible for creating, modifying and searching orders
 */
public class OrderDAO extends BaseDAO {

	/**
	 * Retreives orders that have specified status from database
	 * @param status orders' status
	 * @return list of orders of specified status
	 */
	public List<Order> getOrders(String status) {
		Criteria criteria = session.createCriteria(Order.class);
		criteria.add(Expression.eq("status", status)).addOrder(org.hibernate.criterion.Order.asc("orderedDate"));
		return (List<Order>) criteria.list();
	}

	/**
	 * Retrieves order of specified id from database
	 * @param id order's id
	 * @return order of specified id
	 */
	public Order getOrder(long id) {
		Criteria criteria = session.createCriteria(Order.class);
		criteria.add(Expression.idEq(id));
		Order result = (Order) criteria.uniqueResult();
		return result;
	}

	/**
	 * Updates order in database
	 * @param order order object to be updated
	 */
	public void update(Order order) {
		this.updateObject(order);
	}

	/**
	 * Saves order object in database
	 * @param order order object to be saved
	 */
	public void saveOrder(Order order){
		Transaction transaction = session.beginTransaction();
		for (OrderProduct orderProduct : order.getOrderProducts()) {
			session.save(orderProduct);
		}
		session.save(order.getDelivery());
		session.save(order);
		transaction.commit();
	}
	
	/**
	 * Retrieves orders currently delivered by user of specified id
	 * @param delivererUserId deliverer's id
	 * @return list of orders currently delivered by user of specified id
	 */
	public List<Order> getOrdersInDelivery(long delivererUserId) {
		String hqlQueryText = "from Order order where order.delivery.deliverer = "
				+ delivererUserId
				+ " and order.status = '"
				+ Order.StatusInDelivery + "' order by order.orderedDate asc";
		Query query = session.createQuery(hqlQueryText);
		List<Order> result = query.list();
		return result;
	}

	/**
	 * Retrieves orders associated with customer of specified id
	 * @param customerId customer's id
	 * @return list of orders associated with customer of specified id
	 */
	public List<Order> getOrdersForCustomer(long customerId) {
		String hqlQueryText = "from Order order where order.customer.id = "
				+ customerId + " order by order.orderedDate desc";
		Query query = session.createQuery(hqlQueryText);
		List<Order> result = query.list();
		return result;
	}
	
	/**
	 * Retrieves orders with specified ids
	 * @param ids list of orders' ids
	 * @return list of orders with specified ids
	 */
	public List<Order> getOrders(List<Long> ids){
		Criteria criteria = session.createCriteria(Order.class);
		criteria.add(Expression.in("id", ids));
		List<Order> result = criteria.list();
		return result;
	}
}
